<template>
  <view
    :class="avatarClass"
    :style="avatarStyle"
    @click="handleClick"
  >
    <image
      v-if="src && !imageError"
      :src="src"
      :class="imageClass"
      :mode="mode"
      @error="handleImageError"
      @load="handleImageLoad"
    />
    <view v-else-if="text" :class="textClass">
      {{ displayText }}
    </view>
    <view v-else :class="placeholderClass">
      <text class="i-carbon-user text-2xl"></text>
    </view>

    <!-- 状态指示器 -->
    <view v-if="status" :class="statusClass"></view>

    <!-- 徽章 -->
    <view v-if="badge" class="absolute -top-1 -right-1 bg-novel-primary text-white text-xs rounded-full min-w-5 h-5 flex items-center justify-center">
      {{ badge }}
    </view>
  </view>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'

interface Props {
  // 头像图片地址
  src?: string
  // 备用文字
  text?: string
  // 尺寸
  size?: number | 'small' | 'medium' | 'large'
  // 形状
  shape?: 'circle' | 'square' | 'rounded'
  // 图片裁剪模式
  mode?: 'scaleToFill' | 'aspectFit' | 'aspectFill' | 'widthFix' | 'heightFix'
  // 背景色
  bgColor?: string
  // 文字颜色
  textColor?: string
  // 是否可点击
  clickable?: boolean
  // 状态指示器
  status?: 'online' | 'offline' | 'away' | 'busy'
  // 徽章数字
  badge?: number | string
  // 自定义类名
  customClass?: string
}

const props = withDefaults(defineProps<Props>(), {
  src: '',
  text: '',
  size: 'medium',
  shape: 'circle',
  mode: 'aspectFill',
  bgColor: '',
  textColor: '',
  clickable: false,
  status: '',
  badge: '',
  customClass: '',
})

const emit = defineEmits<{
  click: [event: Event]
  error: [event: Event]
  load: [event: Event]
}>()

const imageError = ref(false)

// 计算尺寸
const sizeValue = computed(() => {
  if (typeof props.size === 'number') {
    return props.size
  }

  const sizeMap = {
    small: 32,
    medium: 48,
    large: 64,
  }

  return sizeMap[props.size]
})

// 计算显示文字（取首字符）
const displayText = computed(() => {
  if (!props.text) return ''
  return props.text.charAt(0).toUpperCase()
})

// 头像样式
const avatarClass = computed(() => {
  const baseClass = 'relative overflow-hidden flex items-center justify-center'

  const shapeClasses = {
    circle: 'rounded-full',
    square: 'rounded-none',
    rounded: 'rounded-custom',
  }

  const sizeClass = typeof props.size === 'number' ? '' : `avatar-${props.size}`

  const interactiveClass = props.clickable
    ? 'cursor-pointer active:scale-95 transition-transform'
    : ''

  return [
    baseClass,
    shapeClasses[props.shape],
    sizeClass,
    interactiveClass,
    props.customClass,
  ].filter(Boolean).join(' ')
})

// 头像内联样式
const avatarStyle = computed(() => {
  const size = typeof props.size === 'number' ? `${sizeValue.value}rpx` : ''
  const bgColor = props.bgColor || (props.text ? 'var(--novel-primary)' : 'var(--bg-light)')
  const textColor = props.textColor || 'var(--text-primary)'

  return {
    width: size,
    height: size,
    backgroundColor: bgColor,
    color: textColor,
    fontSize: size ? `${parseInt(size) * 0.4}rpx` : '',
  }
})

// 图片样式
const imageClass = computed(() => {
  const shapeClasses = {
    circle: 'rounded-full',
    square: '',
    rounded: 'rounded-custom',
  }

  return [
    'w-full h-full object-cover',
    shapeClasses[props.shape],
  ].join(' ')
})

// 文字样式
const textClass = computed(() => {
  const shapeClasses = {
    circle: 'rounded-full',
    square: '',
    rounded: 'rounded-custom',
  }

  return [
    'w-full h-full flex items-center justify-center font-semibold',
    shapeClasses[props.shape],
  ].join(' ')
})

// 占位符样式
const placeholderClass = computed(() => {
  return [
    'w-full h-full flex items-center justify-center text-text-muted',
  ].join(' ')
})

// 状态指示器样式
const statusClass = computed(() => {
  const baseClass = 'absolute bottom-0 right-0 w-3 h-3 rounded-full border-2 border-bg-medium'

  const statusColors = {
    online: 'bg-green-500',
    offline: 'bg-gray-400',
    away: 'bg-yellow-500',
    busy: 'bg-red-500',
  }

  return [
    baseClass,
    statusColors[props.status as keyof typeof statusColors] || '',
  ].join(' ')
})

const handleClick = (event: Event) => {
  if (props.clickable) {
    emit('click', event)
  }
}

const handleImageError = (event: Event) => {
  imageError.value = true
  emit('error', event)
}

const handleImageLoad = (event: Event) => {
  imageError.value = false
  emit('load', event)
}
</script>

<style scoped>
.avatar-small {
  width: 32rpx;
  height: 32rpx;
}

.avatar-medium {
  width: 48rpx;
  height: 48rpx;
}

.avatar-large {
  width: 64rpx;
  height: 64rpx;
}

.active\:scale-95:active {
  transform: scale(0.95);
}
</style>